{
 "cells": [
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "# 1,ChatMessageHistory的使用\n",
   "id": "c903aa79f47d91ad"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-04T15:09:44.023637Z",
     "start_time": "2025-08-04T15:09:43.552724Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 1，实例的创建，方法的调用\n",
    "import uuid\n",
    "\n",
    "from langchain_community.chat_message_histories import ChatMessageHistory\n",
    "from langchain_core.messages import HumanMessage\n",
    "\n",
    "history = ChatMessageHistory()\n",
    "\n",
    "#添加消息的第一种方式\n",
    "history.add_user_message(\"hello\")\n",
    "history.add_ai_message(\"很高兴认识你，我是人工智能助手\")\n",
    "history.add_user_message(\"帮我解释一下1+2*3=？\")\n",
    "\n",
    "print(history.messages)  #返回消息构成的列表"
   ],
   "id": "b77c1783e151dc91",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[HumanMessage(content='hello', additional_kwargs={}, response_metadata={}), AIMessage(content='很高兴认识你，我是人工智能助手', additional_kwargs={}, response_metadata={}), HumanMessage(content='帮我解释一下1+2*3=？', additional_kwargs={}, response_metadata={})]\n"
     ]
    }
   ],
   "execution_count": 1
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-04T15:09:46.992367Z",
     "start_time": "2025-08-04T15:09:44.058245Z"
    }
   },
   "cell_type": "code",
   "source": [
    "from langchain_core.messages import AIMessage, HumanMessage\n",
    "#2，调用LLM\n",
    "import dotenv\n",
    "from langchain_openai import ChatOpenAI\n",
    "import os\n",
    "\n",
    "dotenv.load_dotenv()  #加载当前目录下的 .env 文件\n",
    "\n",
    "os.environ['OPENAI_API_KEY'] = os.getenv(\"OPENAI_API_KEY\")\n",
    "os.environ['OPENAI_BASE_URL'] = os.getenv(\"OPENAI_BASE_URL\")\n",
    "\n",
    "# 创建大模型实例\n",
    "llm = ChatOpenAI(model=\"gpt-4o-mini\")  # 默认使用 gpt-3.5-turbo\n",
    "\n",
    "history = ChatMessageHistory()\n",
    "#添加消息的第2种方式\n",
    "history.add_user_message(HumanMessage(content=\"你好，我是小明\"))\n",
    "history.add_ai_message(AIMessage(content=\"很高兴认识你，我是人工智能助手\"))\n",
    "history.add_user_message(HumanMessage(content=\"帮我解释一下1+2*3=？\"))\n",
    "print(history.messages)"
   ],
   "id": "e961a501ba6362a3",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[HumanMessage(content='你好，我是小明', additional_kwargs={}, response_metadata={}), AIMessage(content='很高兴认识你，我是人工智能助手', additional_kwargs={}, response_metadata={}), HumanMessage(content='帮我解释一下1+2*3=？', additional_kwargs={}, response_metadata={})]\n"
     ]
    }
   ],
   "execution_count": 2
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "# 2,ConversationBufferMemory的使用\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "ConversationBufferMemory的基本使用，使用其主要的api"
   ],
   "id": "7cec661e7ed9705a"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-04T15:09:48.076473Z",
     "start_time": "2025-08-04T15:09:47.784492Z"
    }
   },
   "cell_type": "code",
   "source": [
    "from langchain.memory import ConversationBufferMemory\n",
    "\n",
    "memory = ConversationBufferMemory()\n",
    "#添加信息\n",
    "memory.save_context(\n",
    "    inputs={\"input:\": \"我是人类，我叫小明\"},\n",
    "    outputs={\"output\": \"我是ai助手,我叫小智\"}\n",
    "\n",
    ")\n",
    "memory.save_context(\n",
    "    inputs={\"input:\": \"你好,帮我计算一下1+2*3=？\"},\n",
    "    outputs={\"output\": \"结果是 7\"}\n",
    ")\n",
    "\n",
    "#两种查看结果的方式\n",
    "#第一种\n",
    "# print(memory.chat_memory.messages)\n",
    "\n",
    "#第2种  ：此时此字典的方式返回memory种存储的信息。其默认的key是：history\n",
    "memory.load_memory_variables({})"
   ],
   "id": "e2f9848d6f63da39",
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\Lenovo\\AppData\\Local\\Temp\\ipykernel_4572\\2710194549.py:3: LangChainDeprecationWarning: Please see the migration guide at: https://python.langchain.com/docs/versions/migrating_memory/\n",
      "  memory = ConversationBufferMemory()\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "{'history': 'Human: 我是人类，我叫小明\\nAI: 我是ai助手,我叫小智\\nHuman: 你好,帮我计算一下1+2*3=？\\nAI: 结果是 7'}"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 3
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "#### 体会内部的属性：return_messages\n",
   "id": "8e4e29f8af5cf48"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-04T15:09:48.154139Z",
     "start_time": "2025-08-04T15:09:48.130658Z"
    }
   },
   "cell_type": "code",
   "source": [
    "from langchain.memory import ConversationBufferMemory\n",
    "\n",
    "memory = ConversationBufferMemory(\n",
    "    return_messages=True  #默认值是False  #True 时返回结构化数据信息 False返回文本信息\n",
    "\n",
    ")\n",
    "\n",
    "#添加信息\n",
    "memory.save_context(\n",
    "    inputs={\"input\": \"我是人类，我叫小明\"},  #对应着人类的输入信息,即HumanMessage\n",
    "    outputs={\"output\": \"我是ai助手，我叫小智\"},  #对应着ai的输出信息,即AIMessage\n",
    ")\n",
    "memory.save_context(\n",
    "    inputs={\"input\": \"你好，帮我计算一下1 + 2 * 3 = ？\"},  #对应着人类的输入信息\n",
    "    outputs={\"output\": \"结果是 7 \"},  #对应着ai的输出信息\n",
    ")\n",
    "\n",
    "#此时此字典的方式返回memory种存储的信息。其默认的key是：history!\n",
    "memory.load_memory_variables({})"
   ],
   "id": "b7ef1c6e0c82616",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'history': [HumanMessage(content='我是人类，我叫小明', additional_kwargs={}, response_metadata={}),\n",
       "  AIMessage(content='我是ai助手，我叫小智', additional_kwargs={}, response_metadata={}),\n",
       "  HumanMessage(content='你好，帮我计算一下1 + 2 * 3 = ？', additional_kwargs={}, response_metadata={}),\n",
       "  AIMessage(content='结果是 7 ', additional_kwargs={}, response_metadata={})]}"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 4
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "② 结合LLM,使用PromptTemplate结构,对应着return_messages = False的情况",
   "id": "fd70a3c29438c980"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-04T15:09:50.800442Z",
     "start_time": "2025-08-04T15:09:48.214924Z"
    }
   },
   "cell_type": "code",
   "source": [
    "from langchain.chains.llm import LLMChain\n",
    "from langchain_core.prompts import PromptTemplate, MessagesPlaceholder\n",
    "\n",
    "#1、获取大模型\n",
    "chat_model = ChatOpenAI(\n",
    "    model=\"gpt-4o-mini\"\n",
    ")\n",
    "\n",
    "#2、提供PromptTemplate结构\n",
    "template = \"\"\"\n",
    "我是一个人工智能的助手，可以详细的回复用户的问题。\n",
    "\n",
    "历史问题：{history}\n",
    "\n",
    "当前问题：{question}\n",
    "\n",
    "\"\"\"\n",
    "prompt_template = PromptTemplate.from_template(template)\n",
    "\n",
    "#3、提供ConversationBufferMemory的实例\n",
    "memory = ConversationBufferMemory()\n",
    "\n",
    "#4、提供LLMChain的实例\n",
    "llm_chain = LLMChain(\n",
    "    llm=chat_model,\n",
    "    prompt=prompt_template,\n",
    "    memory=memory,\n",
    ")\n",
    "\n",
    "#5、调用过程\n",
    "llm_chain.invoke({\"question\": \"1 + 3 = ？\"})\n"
   ],
   "id": "5c9eab78969d1ef2",
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\Lenovo\\AppData\\Local\\Temp\\ipykernel_4572\\2508634722.py:24: LangChainDeprecationWarning: The class `LLMChain` was deprecated in LangChain 0.1.17 and will be removed in 1.0. Use :meth:`~RunnableSequence, e.g., `prompt | llm`` instead.\n",
      "  llm_chain = LLMChain(\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "{'question': '1 + 3 = ？', 'history': '', 'text': '1 + 3 = 4。您还有其他问题吗？'}"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 5
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "如上的测试，可以进一步修改为：\n",
   "id": "ec77f2a5c5505bff"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-04T15:09:52.525183Z",
     "start_time": "2025-08-04T15:09:50.876968Z"
    }
   },
   "cell_type": "code",
   "source": [
    "from langchain.chains.llm import LLMChain\n",
    "from langchain_core.prompts import PromptTemplate\n",
    "\n",
    "#1、获取大模型\n",
    "chat_model = ChatOpenAI(\n",
    "    model=\"gpt-4o-mini\"\n",
    ")\n",
    "\n",
    "#2、提供PromptTemplate结构\n",
    "template = \"\"\"\n",
    "我是一个人工智能的助手，可以详细的回复用户的问题。\n",
    "\n",
    "历史问题：{chat_history}\n",
    "\n",
    "当前问题：{question1}\n",
    "\n",
    "\"\"\"\n",
    "prompt_template = PromptTemplate.from_template(template)\n",
    "\n",
    "#3、提供ConversationBufferMemory的实例\n",
    "# ConversationBufferMemory内部的输出结果的key的名称，默认是history。要想\n",
    "#在PromptTemplate中的历史记录中保存，要与PromptTemplate中保存历史记录的变量名相同\n",
    "memory = ConversationBufferMemory(memory_key=\"chat_history\")\n",
    "\n",
    "#4、提供LLMChain的实例\n",
    "llm_chain = LLMChain(\n",
    "    llm=chat_model,\n",
    "    prompt=prompt_template,\n",
    "    memory=memory,\n",
    ")\n",
    "\n",
    "#5、调用过程\n",
    "llm_chain.invoke({\"question1\": \"1 + 3 = ？\"})\n"
   ],
   "id": "ce30bd24f36d0a4",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'question1': '1 + 3 = ？', 'chat_history': '', 'text': '1 + 3 = 4。'}"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 6
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-04T15:09:53.766746Z",
     "start_time": "2025-08-04T15:09:52.561097Z"
    }
   },
   "cell_type": "code",
   "source": "llm_chain.invoke({\"question1\": \"我刚才问了什么问题？\"})",
   "id": "8ac35eafa2725598",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'question1': '我刚才问了什么问题？',\n",
       " 'chat_history': 'Human: 1 + 3 = ？\\nAI: 1 + 3 = 4。',\n",
       " 'text': '你刚才问了“1 + 3 = ？”这个问题，我的回答是“1 + 3 = 4”。如果你有其他问题或者需要进一步的帮助，请随时告诉我！'}"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 7
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "③ 结合LLM,使用ChatPromptTemplate结构,对应着return_messages = True的情况",
   "id": "f8010c8d95ad3609"
  },
  {
   "metadata": {},
   "cell_type": "code",
   "outputs": [],
   "execution_count": null,
   "source": [
    "from langchain.chains.llm import LLMChain\n",
    "from langchain_core.prompts import ChatPromptTemplate\n",
    "from langchain_core.prompts.chat import MessagesPlaceholder\n",
    "\n",
    "#1、获取大模型\n",
    "chat_model = ChatOpenAI(\n",
    "    model=\"gpt-4o-mini\"\n",
    ")\n",
    "\n",
    "#2、提供ChatPromptTemplate结构\n",
    "prompt_template = ChatPromptTemplate.from_messages([\n",
    "    (\"system\", \"我是人工智能助手，可以详细的解决用户问题\"),\n",
    "    MessagesPlaceholder(variable_name=\"chat_history\"),  #要声明在human最后的问题的前面\n",
    "    (\"human\", \"我的问题是{question}\"),\n",
    "])\n",
    "\n",
    "#3、提供ConversationBufferMemory的实例\n",
    "# ConversationBufferMemory内部的输出结果的key的名称，默认是history。要想\n",
    "#在PromptTemplate中的历史记录中保存，要与PromptTemplate中保存历史记录的变量名相同\n",
    "memory = ConversationBufferMemory(\n",
    "    memory_key=\"chat_history\",\n",
    "    return_messages=True\n",
    ")\n",
    "\n",
    "#4、提供LLMChain的实例\n",
    "llm_chain = LLMChain(\n",
    "    llm=chat_model,\n",
    "    prompt=prompt_template,\n",
    "    memory=memory,\n",
    ")\n",
    "\n",
    "#5、调用过程\n",
    "llm_chain.invoke({\"question\": \"1 + 3 = ？\"})\n"
   ],
   "id": "f01a4e50d53bfe31"
  },
  {
   "metadata": {},
   "cell_type": "code",
   "outputs": [],
   "execution_count": null,
   "source": "llm_chain.invoke({\"question\": \"我刚才问了什么问题？\"})",
   "id": "4c97fdd2ef0bef5"
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
